package com.jgp.security.service;

import com.jgp.common.type.RoleType;
import com.jgp.common.utils.JGPUtil;
import com.jgp.security.secmodel.SecRole;
import com.jgp.security.secmodel.SecRoleMenu;
import com.jgp.security.secrepository.SecRoleMenuRepository;
import com.jgp.sys.model.Menu;
import com.jgp.sys.service.MenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 项目   jgp-cloud-parent
 * 作者   loufei
 * 时间   2019-11-03
 */
@Slf4j
@Service
@CacheConfig(cacheNames = "ROLE-MENU-SERVICE")
@Transactional(transactionManager = "secondTransactionManager", readOnly = true)
public class SecRoleMenuService {
    @Lazy
    @Autowired
    private SecRoleMenuRepository repository;
    
    @Autowired
    private MenuService menuService;
    
    /**
     * 修改角色菜单
     *
     * @param roleId
     * @param menuIds
     */
    @Transactional(transactionManager = "secondTransactionManager")
    public void modifyRoleMenu(Long roleId, List<Long> menuIds) {
        List<SecRoleMenu> roleMenus = repository.findByRoleId(roleId);
        List<Long> persistMenuIds = roleMenus.stream().map(SecRoleMenu::getMenuId).collect(Collectors.toList());
        List<Long> same = JGPUtil.intersection(menuIds, persistMenuIds);
        List<Long> dels = JGPUtil.difference(persistMenuIds, same);
        
        if (Objects.nonNull(dels) && dels.size() > 0) {
            repository.deleteByRoleIdAndMenuIdIn(roleId, dels);
        }
        
        List<Long> news = JGPUtil.difference(menuIds, same);
        if (Objects.nonNull(news) && news.size() > 0) {
            List<SecRoleMenu> newItems = new ArrayList<>();
            for (Long menuId : news) {
                SecRoleMenu rm = new SecRoleMenu();
                rm.setMenuId(menuId);
                rm.setRoleId(roleId);
                newItems.add(rm);
            }
            repository.createInBatch(newItems);
        }
    }
    
    /**
     * 查询菜单ID集合
     *
     * @param roleId 角色ID
     * @return
     */
    public List<Long> queryMenuIds(Long roleId) {
        List<SecRoleMenu> menus = repository.findByRoleId(roleId);
        return menus.stream().map(SecRoleMenu::getMenuId).collect(Collectors.toList());
    }
    
    /**
     * 查询菜单
     *
     * @param roles 角色id结合
     * @param type  菜单类型 PC MOBILE PAD
     * @return
     */
    public List<Menu> queryMenus(List<Long> roles, String type) {
        List<SecRoleMenu> roleMenus = repository.findByRoleIdIn(roles);
        List<Long> ids = roleMenus.stream().map(SecRoleMenu::getMenuId).collect(Collectors.toList());
        return menuService.queryForEndPoint(ids, type);
    }
    
    /**
     * 查询菜单
     *
     * @param roles        角色id结合
     * @param endPointType 菜单类型 PC MOBILE PAD
     * @param roleType     用户类型
     * @return
     */
    public List<Menu> queryMenus(List<SecRole> roles, String endPointType, RoleType roleType) {
        
        if (RoleType.SUPER_ADMIN.equals(roleType)) {
            return menuService.queryFull();
        } else if (RoleType.SYS_ADMIN.equals(roleType)) {
            return menuService.querySysAdminMenu(roleType.getWeight());
        } else {
            List<SecRoleMenu> roleMenus = repository.findByRoleIdIn(roles.stream().map(SecRole::getId).collect(Collectors.toList()));
            List<Long> ids = roleMenus.stream().map(SecRoleMenu::getMenuId).collect(Collectors.toList());
            return menuService.queryMenu(ids, endPointType, roleType.getWeight());
        }
    }
}
